/**
 * @author Chad Dettmering
 */

package org.flckphoto;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import android.util.Log;

import com.aetrion.flickr.*;
import com.aetrion.flickr.auth.Auth;
import com.aetrion.flickr.uploader.*;


/**
 * Singleton class that manages Flickr operations
 */
public class FlickrManager {
	/**
	 * Tag for log output
	 */
	private static final String TAG = "FlickrManager";
	
	/**
	 * Flickr api key, needed to access Flickr functions
	 */
	private static final String FLICKR_KEY = "4886cce7247cbe67b2da4ebff67e277b";
	
	/**
	 * Flickr shared secret, needed to access authenticated Flickr functions
	 */
	private static final String FLICKR_SHARED_SECRET = "6bf4f74a185b5072";
	
	/**
	 * singleton instance of this class
	 */
	private static FlickrManager singleton;
	
	/**
	 * the Flickr handle object
	 */
	private Flickr flickr;
	
	/**
	 * the Auth handle object (used to call authenticated Flickr api calls)
	 */
	private Auth auth;
	
	/**
	 * Constructs FlickrManager and obtains the Flickr handle
	 */
	private FlickrManager(){
		auth = null;
		singleton = null;
		
		//try to get a Flickr handle
		try {
			Log.d(TAG, "Creating Flickr handle");
			flickr = new Flickr(FLICKR_KEY, FLICKR_SHARED_SECRET, new REST());
		}
		catch(ParserConfigurationException e){
			flickr = null;
			Log.e(TAG, e.getMessage());
		}
	}
	
	/**
	 * Obtains the singleton instance of this class
	 * @return the singleton instance
	 */
	public static FlickrManager getSingleton() {
		if(singleton == null) {
			Log.d(TAG, "Instantiating FlickrManager singleton instance");
			singleton = new FlickrManager();
		}
		
		return singleton;
	}
	
	/**
	 * Obtains the Flickr handle object from the FlickrManager
	 * @return Flickr handle
	 */
	public Flickr getFlickrInterface() {
		return flickr;
	}
	
	/**
	 * Sets the Auth handle in the FlickrManager
	 * @param _auth the new Auth handle
	 */
	public void setAuthInterface(Auth _auth) {
		auth = _auth;
		flickr.setAuth(auth);
		RequestContext rc = RequestContext.getRequestContext();
		rc.setAuth(auth);
	}
	
	/**
	 * Tells whether or not FlickrManager is authenticated with Flickr or not
	 * @return true if FlickrManager is authenticated, false otherwise
	 */
	public boolean isAuthenticated() {
		try {
			auth = flickr.getAuthInterface().checkToken(Settings.authToken);
			flickr.setAuth(auth);
			RequestContext rc = RequestContext.getRequestContext();
			rc.setAuth(auth);
		}
		catch(FlickrException e) {
			return false;
		}
		catch(SAXException e) {
			return false;
		}
		catch(IOException e) {
			return false;
		}
		
		return true;
	}
	
	/**
	 * Uploads a picture to Flickr
	 * @param picture the picture data to send
	 * @return true if the picture was uploaded successfully, false otherwise
	 */
	public boolean sendPicture(byte[] picture) {
		if(flickr == null) {
			Log.d(TAG, "sendPicture: Flickr handle is null, not uploading");
			return false;
		}
		
		if(!isAuthenticated()) {
			Log.d(TAG, "sendPicture: FlickrManager not authenticatedm not uploading");
			return false;
		}
		
		//get uploader
		Log.d(TAG, "sendPicture: Obtaining uploader interface...");
		Log.d(TAG, auth.getPermission().toString());
		Uploader up = flickr.getUploader();
		
		//I think this is where we can put comments and whatnot
		UploadMetaData data = new UploadMetaData();
		
		//try to upload it
		Log.d(TAG, "sendPicture: Attempting to upload picture data...");
		try {
			up.upload(picture, data);
		}
		catch(FlickrException e) {
			Log.e(TAG, e.getMessage());
			return false;
		}
		catch(IOException e) {
			Log.e(TAG, e.getMessage());
			return false;
		}
		catch(SAXException e) {
			Log.e(TAG, e.getMessage());
			return false;
		}
		Log.d(TAG, "sendPicture: Upload successful");
		return true;
	}
}
